package com.guos.dynamic.expression.spel;

import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.HashMap;
import java.util.Map;

import com.googlecode.aviator.AviatorEvaluator;


/**
 * 每一行代码，都是改变世界的力量
 *
 * @author 郭帅
 * @date 2022/12/2 16:46
 */
public class Test {
    static ExpressionParser parser = new SpelExpressionParser();

    /**
     * 字符串方法调用
     */
    public static void test1() {
        System.out.println("----test1----");
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp1 = parser.parseExpression("'Hello World'.concat('!')");
        String message = (String) exp1.getValue();
        System.out.println(message);
        Expression exp2 = parser.parseExpression("'Hello World'.getBytes().length");
        int length = (Integer) exp2.getValue();
        System.out.println(length);
    }

    /**
     * 获取对象的值，对象不变，使用 StandardEvaluationContext 来进行缓存优化
     */
    public static void test2() {
        System.out.println("----test2----");
        Inventor tesla = new Inventor("Nikola Tesla", "Serbian");

        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("name");

        EvaluationContext context = new StandardEvaluationContext(tesla);
        String name = (String) exp.getValue(context);
        System.out.println(name);

    }

    /**
     * 获取对象的值，对象是动态变化的
     */
    public static void test3() {
        System.out.println("----test3----");
        Inventor tesla = new Inventor("Nikola Tesla", "Serbian");

        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("name");

        String name = (String) exp.getValue(tesla);
        System.out.println(name);

    }


    /**
     * 获取对象的值，并进行比较
     */
    public static void test4() {
        System.out.println("----test4----");
        Inventor tesla = new Inventor("Nikola Tesla", "Serbian");

        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("name == 'Nikola Tesla'");

        Boolean res = exp.getValue(tesla, Boolean.class);
        System.out.println(res);

    }

    public static void test5() {
//        ExpressionParser parser = new SpelExpressionParser();
//        Expression exp1 = parser.parseExpression("'Hello World'.concat('!')");
//        String value = exp1.getValue(String.class);
//        System.out.println("----test5----");
//        Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
//        Object value = parser.parseExpression("name = #newName").getValue(tesla);
//        System.out.println(tesla.getName()); // "Mike Tesla"
//
//        String str = "小哥哥带你使用Aviator";
//        Map<String, Object> env = new HashMap<>();
//        env.put("str", str);
        Long length = (Long) AviatorEvaluator.execute("str");
//        System.out.println(length);
    }

    /**
     * 关系运算符
     */
    public static void test6() {

        System.out.println("----test6----");
        ExpressionParser parser = new SpelExpressionParser();

        // evaluates to true
        boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);
        System.out.println(trueValue);
        // evaluates to false
        boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
        System.out.println(falseValue);
        // evaluates to true
        boolean strTrueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
        System.out.println(strTrueValue);
    }

    /**
     * 判断流程线表达式是否能向下流转<br/>
     * 举例：<br/>
     * 1. 变量a大于10：#a > 10 <br/>
     * 2. 当前日期必须大于申请日期：new java.util.Date().compareTo(#applyTime) > 0
     *
     * @param spelExpression SpEL表达式
     * @param variables      变量
     * @return boolean 是否能向下个节点流转
     * @date 2021/2/28 15:57
     * @author wei.heng
     */
    boolean executeExpression(String spelExpression, Map<String, Object> variables) {

        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setVariables(variables);
        Expression exp = parser.parseExpression(spelExpression);
        return exp.getValue(context, Boolean.class);
    }


    public static void main(String[] args) {
//        test1();
//        test2();
//        test3();
//        test4();
//        test5();
//        test6();
        long l = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            test5();
        }
        System.out.println(System.currentTimeMillis() - l);

    }
}
